package com.jzo2o.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import com.jzo2o.api.publics.MapApi;
import com.jzo2o.api.publics.dto.response.LocationResDTO;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.NumberUtils;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.customer.mapper.AddressBookMapper;
import com.jzo2o.customer.model.domain.AddressBook;
import com.jzo2o.customer.model.dto.request.AddressBookPageQueryReqDTO;
import com.jzo2o.customer.model.dto.request.AddressBookUpsertReqDTO;
import com.jzo2o.customer.service.IAddressBookService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 地址薄 服务实现类
 * </p>
 *
 * @author itcast
 * @since 2023-07-06
 */
@Service
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements IAddressBookService {
    @Resource
    private AddressBookMapper addressBookMapper;

    @Override
    public List<AddressBookResDTO> getByUserIdAndCity(Long userId, String city) {

        List<AddressBook> addressBooks = lambdaQuery()
                .eq(AddressBook::getUserId, userId)
                .eq(AddressBook::getCity, city)
                .list();
        if(CollUtils.isEmpty(addressBooks)) {
            return new ArrayList<>();
        }
        return BeanUtils.copyToList(addressBooks, AddressBookResDTO.class);
    }

    /**
     * 新增地址簿
     *
     * @param dto
     */
    @Override
    public void add(AddressBookUpsertReqDTO dto) {
        AddressBook addressBook = BeanUtil.toBean(dto, AddressBook.class);
        // 填充数据
        Long userId = UserContext.currentUser().getId();
        addressBook.setUserId(userId);
        // 判断是否设置为默认地址，若为默认地址，修改其他默认地址为非默认
        if (dto.getIsDefault()==1) {
            // 若为设置为默认地址，将其他地址的默认地址设置为0
            // 构造查询条件参数
            Wrapper<AddressBook> wrapper = Wrappers.<AddressBook>lambdaQuery()
                    .eq(AddressBook::getUserId,userId)
                    .eq(AddressBook::getIsDefault,1);
            List<AddressBook> addressBookList = addressBookMapper.selectList(wrapper);
            // 判断是否有其他默认地址
            if(CollUtils.isNotEmpty(addressBookList)) {
                // 当集合不为空时，遍历集合，修改每一个默认地址的数据
                addressBookList.forEach(addrBook ->{
                    addrBook.setIsDefault(0);
                    addressBookMapper.updateById(addrBook);
                });
            }
        }
        // 向数据库添加数据
        addressBookMapper.insert(addressBook);
    }

    /**
     * 地址簿分页查询接口
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult<AddressBook> page(AddressBookPageQueryReqDTO dto) {
        // 判断传入参数是否为空
        if (ObjectUtil.isEmpty(dto)) {
            throw new ForbiddenOperationException("传入参数为空");
        }
        // 从线程中获取当前用户id
        Long userId = UserContext.currentUserId();
        Page<AddressBook> page = PageUtils.parsePageQuery(dto, AddressBook.class);
        // 构造查询条件参数
        Wrapper<AddressBook> wrapper = Wrappers.<AddressBook>lambdaQuery()
                .eq(AddressBook::getUserId,userId);
        Page<AddressBook> addressBookPage = addressBookMapper.selectPage(page, wrapper);
        return PageUtils.toPage(addressBookPage,AddressBook.class);
    }

    /**
     * 地址薄详情
     *
     * @param id
     * @return
     */
    @Override
    public AddressBook findById(Long id) {
        AddressBook addressBook = addressBookMapper.selectById(id);
        if(ObjectUtil.isEmpty(addressBook)) {
            throw new ForbiddenOperationException("未查询到该id的地址簿信息");
        }
        return addressBook;
    }

    /**
     * 地址薄修改
     *
     * @param id
     * @param dto
     */
    @Override
    public void update(Long id, AddressBookUpsertReqDTO dto) {
        AddressBook addressBook = BeanUtil.toBean(dto, AddressBook.class);
        addressBook.setId(id);
        if(ObjectUtil.isEmpty(addressBook)) {
            throw new ForbiddenOperationException("未查询到该地址簿信息");
        }
        // 从当前线程中获取用户id
        Long userId = UserContext.currentUserId();
        // 判断是否设置为默认地址
        if (dto.getIsDefault()==1) {
            // 若为设置为默认地址，将其他地址的默认地址设置为0
            // 构造查询条件参数
            Wrapper<AddressBook> wrapper = Wrappers.<AddressBook>lambdaQuery()
                    .eq(AddressBook::getUserId,userId)
                    .eq(AddressBook::getIsDefault,1);
            List<AddressBook> addressBookList = addressBookMapper.selectList(wrapper);
            // 判断是否有其他默认地址
            if(CollUtils.isNotEmpty(addressBookList)) {
                // 当集合不为空时，遍历集合，修改其他默认地址的数据
                addressBookList.forEach(addrBook ->{
                    if (!Objects.equals(addrBook.getId(), addressBook.getId())) {
                        addrBook.setIsDefault(0);
                        addressBookMapper.updateById(addrBook);
                    }
                });
            }
        }
        // 修改当前地址信息
        addressBookMapper.updateById(addressBook);
    }

    /**
     * 设置/取消默认地址
     *
     * @param id
     * @param flag
     */
    @Override
    public void updateDefault(Long id, Integer flag) {
        AddressBook addressBook = this.findById(id);
        Long userId = UserContext.currentUserId();
        // 判断是否设置为默认地址
        if (flag==1) {
            // 若为设置为默认地址，将其他地址的默认地址设置为0
            // 构造查询条件参数
            Wrapper<AddressBook> wrapper = Wrappers.<AddressBook>lambdaQuery()
                    .eq(AddressBook::getUserId,userId)
                    .eq(AddressBook::getIsDefault,1);
            List<AddressBook> addressBookList = addressBookMapper.selectList(wrapper);
            // 判断是否有其他默认地址
            if(CollUtils.isNotEmpty(addressBookList)) {
                // 当集合不为空时，遍历集合，修改 其他 默认地址的数据
                addressBookList.forEach(addrBook ->{
                    if (!Objects.equals(addrBook.getId(), addressBook.getId())) {
                        addrBook.setIsDefault(0);
                        addressBookMapper.updateById(addrBook);
                    }
                });
            }
        }
        // 修改地址簿信息
        addressBookMapper.updateById(addressBook);
    }

    /**
     * 获取默认地址
     *
     * @return
     */
    @Override
    public AddressBook defaultAddress() {
        Long userId = UserContext.currentUserId();
        Wrapper<AddressBook> wrapper = Wrappers.<AddressBook>lambdaQuery()
                .eq(AddressBook::getUserId,userId)
                .eq(AddressBook::getIsDefault,1);
        return addressBookMapper.selectOne(wrapper);
    }
}
